package com.dg.gaming.server.data.mysql;

import java.lang.reflect.*;
import java.sql.*;
import java.sql.Connection;
import java.util.*;

import com.dg.gaming.server.*;
import javolution.util.*;
import java.io.ByteArrayOutputStream;
import java.io.BufferedInputStream;
import com.dg.gaming.api.common.Table;
import com.dg.gaming.server.data.*;
import com.dg.gaming.api.common.User;
import com.dg.gaming.api.common.GameModel;
import nanoxml.XMLElement;
import com.dg.gaming.api.common.msg.*;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2009</p>
 *
 * <p>Company: </p>
 *
 * @author not attributable
 * @version 1.0
 */
public class DBManager {
    private final static ThreadLocal<Connection> connections = new ThreadLocal<
            Connection>();
    private static List<PrepareStatmentObject> psList = Collections.
            synchronizedList(new
                             FastList<PrepareStatmentObject>());

    static {
        psList.add(DBUser.PSO_LOAD_FULL);
        psList.add(DBUser.PSO_LOAD_FULL_WITH_ID);

        psList.add(DBGame.PSO_LOAD_FULL);
        psList.add(DBGame.PSO_LOAD_SIMPLE);
        psList.add(DBGame.PSO_SAVE);

        psList.add(DBCurrentTable.PSO_SAVE);
        psList.add(DBCurrentTable.PSO_LOAD_FULL);

    }

    public synchronized static DBUser getDBUser(String username) throws
            Exception {
        Connection con = getConnection();
        try {
            DBUser dbUser = new DBUser();
            if (dbUser.load(username)) {
                return dbUser;
            } else {
                return null;
            }

        } finally {
            con.rollback();
        }
    }

    public synchronized static DBUser getDBUser(long userId) throws
            Exception {
        Connection con = getConnection();
        try {
            DBUser dbUser = new DBUser();
            if (dbUser.load(userId)) {
                return dbUser;
            } else {
                return null;
            }

        } finally {
            con.rollback();
        }
    }

    public static DBGame getDBGame(long gameId) throws
            Exception {
        DBGame game = new DBGame();
        Connection con = getConnection();
        try {
            if (game.loadFull(gameId)) {
                return game;
            } else {
                return null;
            }

        } finally {
            con.rollback();
        }

    }


    public static DBCurrentTable getDBCurrentTable(long tblId) throws
            Exception {
        DBCurrentTable game = new DBCurrentTable();
        Connection con = getConnection();
        try {
            if (game.loadFull(tblId)) {
                return game;
            } else {
                return null;
            }

        } finally {
            con.rollback();
        }

    }

    public static void saveDBCurrentTable(DBCurrentTable tbl) throws
            Exception {

        Connection con = getConnection();
        try {
            tbl.save();
        } finally {
            con.commit();
        }

    }


    private static Connection getConnection() throws Exception {
        Connection con = connections.get();
        if (con == null) {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost/dg", "dg",
                                              "1");
            connections.set(con);
            con.setAutoCommit(false);
            for (PrepareStatmentObject elem : psList) {
                elem.prepare(con);
            }
        }
        return con;
    }

    public static byte[] loadBytes(java.io.InputStream is) throws Exception {
        BufferedInputStream input = new BufferedInputStream(is);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
        byte[] data = new byte[1024];
        int numRead;

        while ((numRead = input.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, numRead);
        }
        input.close();
        return buffer.toByteArray();

    }

    public static void main(String[] args) {
        for (int i = 0; i < 1; i++) {
            long time = System.currentTimeMillis();
            try {
                DBGame game = getDBGame(1);
                MemoryClassLoader mcl = new MemoryClassLoader(DBGame.class.
                        getClassLoader(), game.getData());
                Class c = mcl.loadClass(game.getModelclassname());
//                Constructor cnst = c.getConstructor();
                GameModel model = (GameModel) c.newInstance();
                DBCurrentTable ct = getDBCurrentTable(1);
                Table tbl = ct.getTable(model);
                tbl.setModel(model);
                tbl.addPlayer(new User("", 1, 0, 0, 0, 0, 0));
                tbl.addPlayer(new User("", 2, 0, 0, 0, 0, 0));

                Method m = c.getMethod("setData", Integer.TYPE, Integer.TYPE,
                                       Integer.TYPE);
                m.invoke(model, 0, 0, 1);
                XMLElement elem = tbl.flatten();
                elem.addChild(model.flatten());
                ct.setMODELDATA(elem.toString().getBytes("UTF8"));
                saveDBCurrentTable(ct);

            } catch (Exception ex) {
                ex.printStackTrace();
            }

        }
    }
}
